package com.lovo.ssc.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lovo.remoteservice.IPayService;
import com.lovo.ssc.bean.OrderGoods;
import com.lovo.ssc.service.ICommodityService;
import com.lovo.ssc.service.IOrderGoodsService;
import com.lovo.ssc.util.DoubleChange;
import com.lovo.ssc.vo.*;
import com.lovo.sscweb.dto.OrderDto;
import com.lovo.ssc.bean.AddressBean;
import com.lovo.ssc.bean.Order;
import com.lovo.ssc.interceptor.CartInterceptor;
import com.lovo.ssc.mapper.OrderMapper;
import com.lovo.ssc.service.IAddressService;
import com.lovo.ssc.service.IOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lovo.sscweb.dto.OrderItemTo;
import com.lovo.util.MQUtil;
import com.lovo.util.SnowIdUtils;
import ma.glasnost.orika.MapperFacade;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author lovo
 * @since 2022-07-11
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private IAddressService addressService;

    @Autowired
    private CartService cartService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private IPayService payService;

    @Autowired
    private ICommodityService commodityService;

    @Autowired
    private IOrderGoodsService orderGoodsService;

    /**
     * 购物车购买确认订单
     *
     * @return
     */
    @Override
    public OrderInfoVo confirmOrder() {
        OrderInfoVo info = new OrderInfoVo();
        UserVo userVo = CartInterceptor.thread.get();
        List<AddressBean> allAddress = addressService.findAllAddress(userVo.getUserId());
        List<CartItem> checkItem = cartService.findCheckItem();
        info.setAddressList(allAddress);
        List<OrderItemVo> orderItems = mapperFacade.mapAsList(checkItem, OrderItemVo.class);
        info.setOrderItems(orderItems);
        double price = 0;
        for (CartItem cartItem : checkItem) {
            if (cartItem != null) {
                price += cartItem.getGoodsPrice() * cartItem.getBuyNum();
            }
        }

        info.setTotalPrice(price);
        info.setPayPrice(DoubleChange.doubleChange(userVo.getUserDiscount() * price));
        info.setDiscount(DoubleChange.doubleChange(price - userVo.getUserDiscount() * price));
        return info;
    }

    @Override
    public List<Order> findByItem(String userName, String startTime, String endTime) {
        return baseMapper.findByItem(userName, startTime, endTime);
    }

    /**
     * 生成订单号
     *
     * @return
     */
    private String greatOrderCode() {
        String orderCode = "";
        String time = LocalDate.now().toString();
        String[] split = time.split("-");
        String year = split[0].substring(2);
        orderCode += year + split[1] + split[2] + "-" + SnowIdUtils.uniqueLong();
        return orderCode;
    }

    /**
     * 购物车购买提交订单
     *
     * @param addressId
     * @return
     */
    @Override
    public OrderDto submitOrder(int addressId, int payMethod) {
        OrderDto orderDto = greteOrderDto(addressId, payMethod);
        //开启消息确认
        rabbitTemplate.setMandatory(true);
        //投递订单
        String s = JSON.toJSONString(orderDto);
        rabbitTemplate.convertAndSend(MQUtil.ORDERFANOUTEXCHANGE, null, s);

        orderSave(orderDto);
        saveOrderItem(orderDto);
        return orderDto;
    }

    /**
     * 购物车创建orderDto
     * @param addressId
     * @param payMethod
     * @return
     */
    private OrderDto greteOrderDto(int addressId, int payMethod) {
        List<CartItem> checkItem = cartService.findCheckItem();
        UserVo userVo = CartInterceptor.thread.get();
        AddressBean address = addressService.findAddressById(addressId);
        OrderDto orderDto = new OrderDto();
        //创建订单
        orderDto.setOrderCode(this.greatOrderCode());
        //订单状态0 未付款
        orderDto.setOrderStatus(0);
        List<OrderItemTo> orderItems = mapperFacade.mapAsList(checkItem, OrderItemTo.class);
        orderDto.setGoodsList(orderItems);
        orderDto.setPlaOrderTime(LocalDate.now().toString());
        orderDto.setShippingAddress(address.getArea() + address.getFullAddress());
        //收货人
        orderDto.setOrderConsignee(address.getReceiver());
        //订单类型
        orderDto.setOrderType("1");
        double price = 0;
        for (CartItem cartItem : checkItem) {
            if (cartItem != null) {
                price += cartItem.getGoodsPrice() * cartItem.getBuyNum();
            }
        }
        orderDto.setOrderTotal(price);
        orderDto.setDiscount(DoubleChange.doubleChange(price - userVo.getUserDiscount() * price));
        orderDto.setPayPrice(DoubleChange.doubleChange(userVo.getUserDiscount() * price));
        orderDto.setUsername(userVo.getUserName());
        orderDto.setMethodPayment(payMethod);
        return orderDto;
    }

    @Override
    public int findOrderState(String orderCode) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("orderCode", orderCode);
        Order order = baseMapper.selectOne(wrapper);
        return order.getOrderStatus();
    }

    @Override
    public void updateOrderState(String orderCode) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("orderCode", orderCode);
        Order order = baseMapper.selectOne(wrapper);
        order.setOrderStatus(1);
        baseMapper.update(order, wrapper);
    }

    /**
     * 本地保存订单
     *
     * @param orderDto
     */
    private void orderSave(OrderDto orderDto) {
        //本地保存订单信息
        Order order = new Order();
        order.setOrderCode(orderDto.getOrderCode());
        //订单状态未支付
        order.setOrderStatus(orderDto.getOrderStatus());
        order.setShippingAddress(orderDto.getShippingAddress());
        order.setOrderTotal(orderDto.getOrderTotal());
        order.setPlaOrderTime(orderDto.getPlaOrderTime());
        order.setDiscount(orderDto.getDiscount());
        order.setPayPrice(orderDto.getPayPrice());
        order.setUserName(orderDto.getUsername());
        order.setOrderConsignee(orderDto.getOrderConsignee());
        order.setType(orderDto.getOrderType());
        order.setMethodPayment(orderDto.getMethodPayment());
        baseMapper.insert(order);

    }

    /**
     * 购物车商品保存
     * @param orderDto
     */
    private void saveOrderItem(OrderDto orderDto) {
        //保存订单商品信息
        List<CartItem> checkItem = cartService.findCheckItem();
        List<OrderItemTo> list = mapperFacade.mapAsList(checkItem, OrderItemTo.class);
        for (int i = 0; i < list.size(); i++) {
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderCode(orderDto.getOrderCode());
            orderGoods.setGoodsCode(list.get(i).getGoodsCode());
            orderGoods.setGoodsName(list.get(i).getGoodsName());
            for (int j = 0; j < list.get(i).getGoodsBatch().size(); j++) {
                orderGoods.setGoodsBatch(list.get(i).getGoodsBatch().get(j));
            }
//            List<String> batchByCode = commodityService.findBatchByCode(list.get(i).getGoodsCode(), list.get(i).getBuyNum());
//            if (batchByCode.size() > 0 && batchByCode != null) {
//                for (int k = 0; k < batchByCode.size(); k++) {
//
//                }
//            }
//            orderGoods.setGoodsBatch("1");
            orderGoods.setGoodNumber(list.get(i).getBuyNum());
            orderGoodsService.add(orderGoods);
        }
    }

    /**
     * 直接购买确认
     *
     * @param commodity
     * @return
     */
    @Override
    public OrderInfoVo directBuy(OrderItemTo commodity) {
        System.out.println(commodity);
        List<String> batchByCode = commodityService.findBatchByCode(commodity.getGoodsCode(), commodity.getBuyNum());
        commodity.setGoodsBatch(batchByCode);
        OrderInfoVo info = new OrderInfoVo();
        UserVo userVo = CartInterceptor.thread.get();
        List<AddressBean> allAddress = addressService.findAllAddress(userVo.getUserId());
        info.setAddressList(allAddress);
        List<OrderItemVo> orderItems = new ArrayList<>();
        OrderItemVo vo = new OrderItemVo();
        BeanUtils.copyProperties(commodity,vo);
        orderItems.add(vo);
        info.setOrderItems(orderItems);

        double price = 0;
        for (OrderItemVo orderItemVo:orderItems) {
            if (orderItemVo != null) {
                price += orderItemVo.getGoodsPrice() * orderItemVo.getBuyNum();
            }
        }
        info.setTotalPrice(price);
        info.setPayPrice(DoubleChange.doubleChange(userVo.getUserDiscount() * price));
        info.setDiscount(DoubleChange.doubleChange(price - userVo.getUserDiscount() * price));

        return info;
    }

    /**
     * 直接购买提交
     * @param commodity
     * @param addressId
     * @param payMethod
     * @return
     */
    @Override
    public OrderDto directSubmit(int addressId, int payMethod,OrderItemTo commodity) {
        OrderDto dto = getOrderDto(addressId, payMethod, commodity);


        //开启消息确认
        rabbitTemplate.setMandatory(true);
        //投递订单
        String s = JSON.toJSONString(dto);
        rabbitTemplate.convertAndSend(MQUtil.ORDERFANOUTEXCHANGE, null, s);

        this.orderSave(dto);
        this.directSave(dto);

        return dto;
    }

    /**
     * 直接购买创建OrderDto
     * @param addressId
     * @param payMethod
     * @param commodity
     * @return
     */
    private OrderDto getOrderDto(int addressId, int payMethod, OrderItemTo commodity) {
        System.out.println(commodity);
        OrderDto dto = new OrderDto();
        AddressBean address = addressService.findAddressById(addressId);
        UserVo userVo = CartInterceptor.thread.get();
        String userName = userVo.getUserName();
        String orderCode = this.greatOrderCode();
        dto.setOrderCode(orderCode);
        //订单状态
        dto.setOrderStatus(0);
        dto.setPlaOrderTime(LocalDate.now().toString());
        dto.setShippingAddress(address.getArea() + address.getFullAddress());
        //收货人
        dto.setOrderConsignee(address.getReceiver());
        dto.setUsername(userName);
        List<OrderItemTo> goodsList = new ArrayList<>();
        goodsList.add(commodity);
        dto.setGoodsList(goodsList);
        dto.setMethodPayment(payMethod);

        double price = 0;
        for (OrderItemTo orderItemTo :goodsList) {
            if (orderItemTo != null) {
                price += orderItemTo.getGoodsPrice() * orderItemTo.getBuyNum();
            }
        }

        dto.setOrderType("1");
        dto.setOrderTotal(DoubleChange.doubleChange(price));
        dto.setDiscount(DoubleChange.doubleChange(userVo.getUserDiscount() * price));
        dto.setPayPrice(DoubleChange.doubleChange(price - userVo.getUserDiscount() * price));
        return dto;
    }

    private void directSave(OrderDto dto){
        List<OrderItemTo> goodsList = dto.getGoodsList();
        for (int i = 0;i<goodsList.size();i++) {
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderCode(dto.getOrderCode());
            orderGoods.setGoodsCode(goodsList.get(i).getGoodsCode());
            orderGoods.setGoodsName(goodsList.get(i).getGoodsName());
            for (int j = 0; j < goodsList.get(i).getGoodsBatch().size(); j++) {
                orderGoods.setGoodsBatch(goodsList.get(i).getGoodsBatch().get(j));
            }
            orderGoods.setGoodNumber(goodsList.get(i).getBuyNum());
            orderGoodsService.add(orderGoods);
        }
    }



    @Override
    public boolean consumption(int addressId, int payMethod) {
        List<CartItem> checkItem = cartService.findCheckItem();
        UserVo userVo = CartInterceptor.thread.get();
        AddressBean address = addressService.findAddressById(addressId);
        OrderDto orderDto = new OrderDto();
        //创建订单
        orderDto.setOrderCode(this.greatOrderCode());
        //订单状态0 未付款
        orderDto.setOrderStatus(0);
        List<OrderItemTo> orderItems = mapperFacade.mapAsList(checkItem, OrderItemTo.class);
        orderDto.setGoodsList(orderItems);
        orderDto.setPlaOrderTime(LocalDate.now().toString());
        orderDto.setShippingAddress(address.getArea() + address.getFullAddress());
        //收货人
        orderDto.setOrderConsignee(address.getReceiver());
        //订单类型
        orderDto.setOrderType("1");
        double price = 0;
        for (CartItem cartItem : checkItem) {
            if (cartItem != null) {
                price += cartItem.getGoodsPrice() * cartItem.getBuyNum();
            }
        }
        orderDto.setOrderTotal(price);
        orderDto.setDiscount(DoubleChange.doubleChange(price - userVo.getUserDiscount() * price));
        orderDto.setPayPrice(DoubleChange.doubleChange(userVo.getUserDiscount() * price));
        orderDto.setUsername(userVo.getUserName());
        orderDto.setMethodPayment(payMethod);

        this.orderSave(orderDto);
        this.saveOrderItem(orderDto);

        String userName = orderDto.getUsername();
        float payPrice = (float) orderDto.getPayPrice();
        List<OrderItemTo> goodsList = orderDto.getGoodsList();
        String str = JSON.toJSONString(goodsList);
        boolean result = payService.consumption(userName, payPrice, "null");
        if (result != true) {

            return false;
        }
        this.updateOrderState(orderDto.getOrderCode());
        return true;
    }

    @Override
    public String getPayResult(String userCode) {
        Object o = payService.consumeConfirm(userCode);
        return o.toString();
    }

    @Override
    public boolean directThird(int addressId, int payMethod,OrderItemTo commodity){
        System.out.println(commodity);
        OrderDto dto = new OrderDto();
        AddressBean address = addressService.findAddressById(addressId);
        UserVo userVo = CartInterceptor.thread.get();
        String userName = userVo.getUserName();
        String orderCode = this.greatOrderCode();
        dto.setOrderCode(orderCode);
        //订单状态
        dto.setOrderStatus(0);
        dto.setPlaOrderTime(LocalDate.now().toString());
        dto.setShippingAddress(address.getArea() + address.getFullAddress());
        //收货人
        dto.setOrderConsignee(address.getReceiver());
        dto.setUsername(userName);
        List<OrderItemTo> goodsList = new ArrayList<>();
        goodsList.add(commodity);
        dto.setGoodsList(goodsList);
        dto.setMethodPayment(payMethod);

        double price = 0;
        for (OrderItemTo orderItemTo :goodsList) {
            if (orderItemTo != null) {
                price += orderItemTo.getGoodsPrice() * orderItemTo.getBuyNum();
            }
        }

        dto.setOrderType("1");
        dto.setOrderTotal(DoubleChange.doubleChange(price));
        dto.setDiscount(DoubleChange.doubleChange(userVo.getUserDiscount() * price));
        dto.setPayPrice(DoubleChange.doubleChange(price - userVo.getUserDiscount() * price));

        this.orderSave(dto);
        this.directSave(dto);

        float payPrice = (float) dto.getPayPrice();
        List<OrderItemTo> goodsList1 = dto.getGoodsList();
        String str = JSON.toJSONString(goodsList1);
        boolean result = payService.consumption(userName, payPrice, "null");
        if (result != true) {

            return false;
        }
        this.updateOrderState(dto.getOrderCode());
        return true;
    }
}
